; Disassembly of the file "z:\ramdisk\home\knoppix\none\2716 BOOT 80K EPROM green CoBra.bin"
; 
; CPU Type: Z80
; 
; Created with dZ80 2.0
; 
; on Saturday, 08 of September 2012 at 07:37 PM
;
; Lines containing direct values of video addresses have been marked as *n* where n is a number
; Proper modification of these lines can make the graphic logo work if video RAM is located
; at a different address than C000. In total I found 58 such lines.
;
; Also lines that must to be modified for this code to run relocated have been marked with ---@@@
;
;				############################## START ROUTINE ####################################
;
0000           LD      A,$83	; bit 7 = "1"
0002           LD      R,A	; u36/5 kept at "1" after NPOR="0", so the computer stays in the startup hw config
0004           LD      SP,$FD73	; set stack at FD73
0007           LD      HL,$C000	; *0* C000 is the start addr for video mem in startup hw configuration (C0->40 @ 0009)
000A           LD      DE,$C001	; *1* C001 is the start addr+1 for video mem in startup hw configuration (C0->40 @ 000C)
000D           LD      BC,$1AFF	; 1AFF+1 is the standard total size of Spectrum video memory
0010           LD      (HL),$00	; this will fill up all video memory with zeros when the LDIR below executes
0012           LDIR
0014           LD      HL,$0000	; start address of this BOOT EPROM code				---@@@(1)0016:00->10
0017           LD      DE,$8000	; start address of DRAM#0 in the startup config
001A           LD      BC,$0800	; 0800h (2K) is the length of this BOOT EPROM code
001D           LDIR		; entire BOOT EPROM code is copied from EPROM into DRAM#0
001F           LD      A,$03	; channel control word for Z80CTC, used in the next 4 instructions:
;				; (Disable Interrupt, Timer mode, Prescaler=16, CLK/TRG Falling Edge,
;				; Auto Trigger, No Time Const. Follows, Reset Channel)
0021           OUT     ($E3),A	; reset CTC channel 0
0023           OUT     ($EB),A	; reset CTC channel 1
0025           OUT     ($F3),A	; reset CTC channel 2
0027           OUT     ($FB),A	; reset CTC channel 3
0029           XOR     A	; set A register to "00"
002A           OUT     ($FD),A	; write "00" to 8272 Data Register (invalid command, places 8272 in standby)
002C           LD      A,$92	; control word for 8255: Mode Set flag=active,
;				; 			Group A: Select Mode 0,
;				;				 Port A set to Input mode,
;				;				 Port C (upper half) set to Output Mode,
;				;			Group B: Select Mode 0,
;				;				 Port B set to Input Mode,
;				;				 Port C (lower half) set to Output Mode
002E           OUT     ($DF),A	; write control word to 8255
0030           OUT     ($DF),A	; write control word to 8255 (again !?)
0032           LD      A,$40
0034           OUT     ($FE),A	; write 40 to port C of 8255
;				; (set border to black, set signal "SO" to 0, set signal "O5" to 0,
;				;  set signal "O6" to 1 to allow access to video memory in the hw startup config)
0036           JR      $0056	;###################### START ROUTINE CONTINUES AT 0056 #########################
;
;				############################## BASIC CONFIGURATION ##############################
;
0038           LD      HL,$4000	; 4000 is the start addr of BASIC EPROM in the startup hw config
003B           LD      DE,$8000	; 8000 is the start addr of DRAM#0 in the startup hw config
003E           LD      BC,$4000	; 4000 is the length of the SPECTRUM BASIC code (16 KB)
0041           LDIR		; copy SPECTRUM BASIC code into DRAM#0
0043           EXX		; (after EXX, HL contains 0000, see line 07F4)
0044           LD      A,$03	;	SAME AS	]
0046           OUT     ($E3),A	;		]
0048           OUT     ($EB),A	;	001F	]
004A           OUT     ($F3),A	;		]
004C           OUT     ($FB),A	;	 to	]
004E           XOR     A	;		]
004F           OUT     ($FD),A	;	002A	]
0051           OUT     ($FE),A	; write 03 to port C of 8255	 <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--|
;				; (set border to white, set signal "SO" to 0, set signal "O5" to 0,				|
;				;  set signal "O6" to 0)									|
0053           LD      R,A	; set bit 7 of R to 0, prepare for BASIC hardware configuration					|
0055           JP      (HL)	; change hardware configuration with a jump to (HL)						|
;																|
;				############################# END OF BASIC CONFIGURATION ########################		|
;																|
;				; ###################### START ROUTINE CONTINUED ################################		|
0056           LD      A,$FE	; upper half of address bus at I/O time in next instruction (test keyboard row KA8)		|
0058           IN      A,($FE)	; read port A of 8255										|
005A           BIT     5,A	; keyboard test for CTRL key (test keyboard column K5)						|
005C           JR      NZ,$0091	; jump to 0091 if CTRL is not pressed								|
005E           XOR     A	; set A to "00" (upper half of address bus at I/O time in next instruction) <--- <--- <-|	|
005F           IN      A,($FE)	; read port A of 8255 (test keyboard, all rows)						|	|
0061           OR      $40	; set bit 6										|	|
0063           XOR     $20	; invert bit 5										|	|
0065           OUT     ($FE),A	; write result to port C of 8255 (set "O6" to 1, "O5" to 1 - since CTRL is pressed)	|	|
0067           LD      HL,$55AA	;											|	|
006A           LD      ($1555),HL	;										|	|
006D           LD      ($4CCC),HL	;										|	|
0070           LD      ($8F0F),HL	;										|	|
0073           LD      ($C0FF),HL	;										|	|
0076           LD      HL,($1555)	;										|	|
0079           LD      HL,($4CCC)	;										|	|
007C           LD      HL,($8F0F)	;										|	|
007F           LD      HL,($C0FF)	;										|	|
0082           AND     $03	; test bits 0 and 1 (keys "A" and "S")							|	|
0084           JR      NZ,$005E	; if they are both 1 (keys not pressed), jump back to 005E ---> ---> ---> ---> ---> --->|	|
0086           IN      A,($FE)	; read port A of 8255										|
0088           AND     $40	; test bit 6 (Tape Input)									|
008A           LD      HL,$005E	; set jump address in new config to 005E							|
008D           JR      Z,$0051	; if Tape Input=0 jump to 0051 ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---->|
008F           JR      $0051	; jump to 0051 anyway
;
;				######## COBRA GRAPHIC LOGO ###########
;
0091           LD      HL,$D900	; *2* video attr start addr for 2nd third of video RAM in startup hw cfg (D9->59 @ 0093)
0094           LD      B,$08
0096           PUSH    BC
0097           LD      BC,$0C05	; write "05" as color attribute
009A           LD      (HL),C	; for the first 12 characters
009B           INC     HL	; of the middle third in the
009C           DJNZ    $009A	; Spectrum screen (INK=cyan, PAPER=black)
009E           LD      BC,$1403	;	write "03" as color attribute
00A1           LD      (HL),C	;	for the next 20 characters
00A2           INC     HL	;	(INK==white, PAPER=black)
00A3           DJNZ    $00A1	;	so in total 32 characters (one line)
00A5           POP     BC
00A6           DJNZ    $0096	; repeat the above 7 times,(all 8 lines in the middle third of screen)
00A8           EXX
00A9           LD      HL,$0188	; HL' used as pointer to data block start address (0188)	---@@@(2)00AB:01->11
00AC           EXX
00AD           LD      HL,$CBB9	; *3* address within serial video RAM, middle third of screen (CB->4B @ 00AF)
00B0           LD      DE,$01FE	; data to be written in there
00B3           LD      A,$04
00B5           LD      B,$09
00B7           PUSH    BC	; <--- <--- <--- <--- <--- <--- <--- <--- <--- <---
00B8           LD      B,A	;						  |
00B9           LD      (HL),D	; write "01" at CBB9 <--- <--- <- <--- <-|	  |
00BA           INC     HL	;				|	 |	  |
00BB           LD      (HL),E	; write "FE" at CBBA		|	 |	  |
00BC           EXX		;				|	 |	  |
00BD           LD      A,(HL)	; read first byte of data (FF)	|	 |	  |
00BE           INC     HL	; increment pointer (HL'=0189)	|	 |	  |
00BF           EXX		;				|	 |	  |
00C0           LD      C,A	; C = data byte			|	 |	  |
00C1           ADD     A,L	; A = data byte + L = B9 + CY	|	 |	  |
00C2           LD      L,A	; L = data byte + L		|	 |	  |
00C3           JR      NC,$00C6	;				|	 |	  |
00C5           INC     H	; H=CB+1=CC			|	 |	  |
00C6           DJNZ    $00B9	; ---> ---> ---> ---> ---> --->>>	 |	  |
00C8           LD      B,C	;					 |	  |
00C9           EXX		;					 |	  |
00CA           LD      E,(HL)	; Read 2 bytes				 |	  |
00CB           INC     HL	; of data into				 |	  |
00CC           LD      D,(HL)	; DE' register.				 |	  |
00CD           INC     HL	; Increment pointer			 |	  |
00CE           PUSH    DE	;					 |	  |
00CF           EXX		;					 |	  |
00D0           POP     HL	; HL = 2 data bytes			 |	  |
00D1           SLA     E	;					 |	  |
00D3           RL      D	;					 |	  |
00D5           JR      NC,$00B9	; ---> ---> ---> ---> ---> ---> ---> --->>	  |
00D7           RR      D	;						  |
00D9           RR      E	;						  |
00DB           LD      D,$FF	;						  |
00DD           SLA     D	; <----						  |
00DF           RL      E	;     |						  |
00E1           JR      C,$00DD	; ---->						  |
00E3           LD      A,D	;						  |
00E4           CPL		;						  |
00E5           LD      D,A	;						  |
00E6           LD      E,$FF	;						  |
00E8           LD      A,C	;						  |
00E9           POP     BC	;						  |
00EA           DJNZ    $00B7	; ---> ---> ---> ---> ---> ---> ---> ---> ---> --->
00EC           LD      E,L
00ED           LD      D,H
00EE           EXX
00EF           PUSH    HL
00F0           EXX
00F1           POP     HL
00F2           LD      B,$0B
00F4           PUSH    BC	; <--- <---
00F5           LD      B,A	;	  |
00F6           LD      A,(HL)	;	  |
00F7           INC     HL	;	  |
00F8           LD      (DE),A	; <----   |
00F9           INC     DE	;     |   |
00FA           DJNZ    $00F8	; ---->   |
00FC           LD      A,(HL)	;	  |
00FD           INC     HL	;	  |
00FE           LD      E,(HL)	;	  |
00FF           INC     HL	;	  |
0100           LD      D,(HL)	;	  |
0101           INC     HL	;	  |
0102           POP     BC	;	  |
0103           DJNZ    $00F4	; ---> --->
0105           LD      HL,$03E0	; addr of color attr for color pattern under logo (within data block)	---@@@(3)0107:03->13
0108           LD      DE,$DA8C	; *4* addr of color attr for color pattern under logo (within video mem) (DA->5A @ 010A)
010B           LD      BC,$0008	; length of color pattern under logo
010E           LDIR
0110           LD      D,$07	; ######### BEGINNING OF ONE SCREEN CYCLE (KBD READ + SCROLL LEFT) #########
0112           LD      BC,$0000
0115           LD      A,$78	; keyboard test, rows KA15 ("B" key), KA10 ("W" key), KA9 ("D" key), KA8 ("C" key)
0117           IN      A,($FE)
0119           RRA
011A           RRA
011B           JP      NC,$07F4	; if "W" pressed, jump to OPUS loading routine			---@@@(4)011D:07->17
011E           RRA
011F           JP      NC,$0552	; if "D" pressed, jump to CP/M loading routine			---@@@(5)0121:05->15
0122           RRA
0123           JP      NC,$0537	; if "C" pressed, jump to tape loading routine			---@@@(6)0125:05->15
0126           RRA
0127           JP      NC,$07F0	; if "B" pressed, jump to BASIC loading routine			---@@@(7)0129:07->17
012A           RRA
012B           JP      NC,$0497	; if "F4" or "CTRL" pressed, jump to checksum routine		---@@@(8)012D:04->14
012E           DJNZ    $0115	; cycle the above 256 times
0130           DEC     C
0131           JR      NZ,$0115	; cycle the above 256 times (65536 times total)
0133           DEC     D
0134           JR      NZ,$0115	; cycle the above 7 times (458752 times total)
0136           LD      B,$20
0138           PUSH    BC	; BC=2000
0139           CALL    $0159	; call SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS		---@@@(9)013B:01->11
013C           LD      HL,$D901	; *5* video attr start addr for 2nd third of video RAM in startup hw cfg (D9->59 @ 013E)
013F           LD      B,$08	; 	  ######## 00D5-00E7 mid screen attribute scroll left 1 char ########
0141           PUSH    BC	; BC=0800 (B=08 used as row counter)    <--- <--- <--- <--- <---|
0142           LD      BC,$001F	; screen width in chars minus 1					|
0145           LD      D,H	;								|
0146           LD      E,L	; DE=D901							|
0147           DEC     E	; DE=D900 (start of row 1 (of 8) of attr's for middle third of screen)
0148           LD      A,(DE)	; copy the first attr byte on the row				|
0149           LDIR		; shift 31 attribute bytes left, first byte overwritten		|
014B           LD      (DE),A	; save the former first byte into the last on the row		|
014C           INC     L	; HL now points to first char on next row			|
014D           INC     E	; DE now points to last char on row				|
014E           POP     BC	; POP back the row counter					|
014F           DJNZ    $0141	; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ->|    ########
0151           CALL    $0159	; call SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS		---@@@(10)0153:01->11
0154           POP     BC
0155           DJNZ    $0138
0157           JR      $0110	; ###### END COBRA GRAPHIC LOGO ROUTINE #########

0159           LD      B,$04	; ######## SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS ########
015B           PUSH    BC
015C           LD      HL,$CFFF	; *6* address within video memory (CF->4F @ 015E)
015F           LD      B,$08
0161           PUSH    BC
0162           LD      B,$08
0164           PUSH    BC
0165           LD      D,H
0166           LD      E,L
0167           LD      B,$20
0169           SCF
016A           RL      (HL)
016C           DEC     HL
016D           DJNZ    $016A
016F           JR      C,$0174
0171           LD      A,(DE)
0172           DEC     A
0173           LD      (DE),A
0174           POP     BC
0175           OR      A
0176           LD      DE,$00E0
0179           SBC     HL,DE
017B           DJNZ    $0164
017D           LD      BC,$07E0
0180           ADD     HL,BC
0181           POP     BC
0182           DJNZ    $0161
0184           POP     BC
0185           DJNZ    $015B
0187           RET		; ######## SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS END #############

0188           DB      $FF	; ############## GRAPHIC DATA BLOCK ################
0189           DB      $E0
018A           DB      $FF
018B           DB      $1F
018C           DB      $B1
018D           DB      $C8	; *7*	(C8->48)
018E           DB      $45
018F           DB      $B9
0190           DB      $22
0191           DB      $02
0192           DB      $1F
0193           DB      $A2
0194           DB      $16
0195           DB      $22
0196           DB      $02
0197           DB      $1F
0198           DB      $A2
0199           DB      $16
019A           DB      $25
019B           DB      $15
019C           DB      $09
019D           DB      $75
019E           DB      $43
019F           DB      $25
01A0           DB      $BC
01A1           DB      $02
01A2           DB      $19
01A3           DB      $25
01A4           DB      $BC
01A5           DB      $02
01A6           DB      $19
01A7           DB      $07
01A8           DB      $1D
01A9           DB      $D9
01AA           DB      $07
01AB           DB      $1D
01AC           DB      $0C
01AD           DB      $9A
01AE           DB      $C8	; *8*	(C8->48)
01AF           DB      $07
01B0           DB      $A5
01B1           DB      $90
01B2           DB      $FF
01B3           DB      $88
01B4           DB      $FF
01B5           DB      $E5
01B6           DB      $FF
01B7           DB      $FF
01B8           DB      $31
01B9           DB      $07
01BA           DB      $0C
01BB           DB      $82
01BC           DB      $C8	; *9*	(C8->48)
01BD           DB      $FF
01BE           DB      $FF
01BF           DB      $FF
01C0           DB      $6D
01C1           DB      $7F
01C2           DB      $09
01C3           DB      $07
01C4           DB      $F7
01C5           DB      $07
01C6           DB      $DF
01C7           DB      $FF
01C8           DB      $09
01C9           DB      $CC
01CA           DB      $C8	; *10*	(C8->48)
01CB           DB      $7B
01CC           DB      $92
01CD           DB      $FF
01CE           DB      $FF
01CF           DB      $EB
01D0           DB      $FF
01D1           DB      $FF
01D2           DB      $C4
01D3           DB      $10
01D4           DB      $AF
01D5           DB      $C8	; *11*	(C8->48)
01D6           DB      $FC
01D7           DB      $02
01D8           DB      $FC
01D9           DB      $02
01DA           DB      $FC
01DB           DB      $02
01DC           DB      $FC
01DD           DB      $02
01DE           DB      $FC
01DF           DB      $02
01E0           DB      $FC
01E1           DB      $02
01E2           DB      $0B
01E3           DB      $F3
01E4           DB      $0B
01E5           DB      $06
01E6           DB      $87
01E7           DB      $C8	; *12*	(C8->48)
01E8           DB      $C0
01E9           DB      $FF
01EA           DB      $FF
01EB           DB      $72
01EC           DB      $FF
01ED           DB      $0B
01EE           DB      $46
01EF           DB      $C8	; *13*	(C8->48)
01F0           DB      $74
01F1           DB      $6E
01F2           DB      $3D
01F3           DB      $52
01F4           DB      $8E
01F5           DB      $9F
01F6           DB      $FE
01F7           DB      $DD
01F8           DB      $FF
01F9           DB      $82
01FA           DB      $11
01FB           DB      $8C
01FC           DB      $C8	; *14*	(C8->48)
01FD           DB      $62
01FE           DB      $55
01FF           DB      $20
0200           DB      $E1
0201           DB      $70
0202           DB      $8E
0203           DB      $DA
0204           DB      $A3
0205           DB      $7A
0206           DB      $5F
0207           DB      $9F
0208           DB      $5F
0209           DB      $CC
020A           DB      $2A
020B           DB      $28
020C           DB      $08
020D           DB      $0B
020E           DB      $62
020F           DB      $C8	; *15*	(C8->48)
0210           DB      $E5
0211           DB      $FF
0212           DB      $FF
0213           DB      $59
0214           DB      $F7
0215           DB      $07
0216           DB      $A5
0217           DB      $70
0218           DB      $B6
0219           DB      $D1
021A           DB      $13
021B           DB      $D1
021C           DB      $C8	; *16*	(C8->48)
021D           DB      $02
021E           DB      $02
021F           DB      $01
0220           DB      $88
0221           DB      $37
0222           DB      $07
0223           DB      $2E
0224           DB      $90
0225           DB      $3F
0226           DB      $A5
0227           DB      $8B
0228           DB      $BF
0229           DB      $02
022A           DB      $F9
022B           DB      $FF
022C           DB      $FF
022D           DB      $02
022E           DB      $02
022F           DB      $08
0230           DB      $D1
0231           DB      $CA	; *17*	(CA->4A)
0232           DB      $76
0233           DB      $90
0234           DB      $ED
0235           DB      $9A
0236           DB      $2E
0237           DB      $E8
0238           DB      $07
0239           DB      $09
023A           DB      $CC
023B           DB      $C9	; *18*	(C9->49)
023C           DB      $7B
023D           DB      $86
023E           DB      $78
023F           DB      $92
0240           DB      $EB
0241           DB      $9F
0242           DB      $27
0243           DB      $FC
0244           DB      $0B
0245           DB      $AC
0246           DB      $C8	; *19*	(C8->48)
0247           DB      $22
0248           DB      $0B
0249           DB      $F3
024A           DB      $FC
024B           DB      $FF
024C           DB      $FA
024D           DB      $FF
024E           DB      $C7
024F           DB      $FF
0250           DB      $1C
0251           DB      $03
0252           DB      $BB
0253           DB      $CD	; *20*	(CD->4D)
0254           DB      $B4
0255           DB      $F6
0256           DB      $10
0257           DB      $2A
0258           DB      $C8	; *21*	(C8->48)
0259           DB      $C6
025A           DB      $54
025B           DB      $03
025C           DB      $FD
025D           DB      $72
025E           DB      $38
025F           DB      $F5
0260           DB      $DC
0261           DB      $7B
0262           DB      $30
0263           DB      $02
0264           DB      $F8
0265           DB      $32
0266           DB      $A6
0267           DB      $26
0268           DB      $0C
0269           DB      $66
026A           DB      $C8	; *22*	(C8->48)
026B           DB      $28
026C           DB      $FC
026D           DB      $BB
026E           DB      $FF
026F           DB      $DE
0270           DB      $FB
0271           DB      $E4
0272           DB      $BA
0273           DB      $08
0274           DB      $FA
0275           DB      $07
0276           DB      $01
0277           DB      $46
0278           DB      $CF	; *23*	(CF->4F)
0279           DB      $01
027A           DB      $46
027B           DB      $CE	; *24*	(CE->4E)
027C           DB      $05
027D           DB      $CC
027E           DB      $CA	; *25*	(CA->4A)
027F           DB      $FF
0280           DB      $FA
0281           DB      $7E
0282           DB      $45
0283           DB      $01
0284           DB      $46
0285           DB      $CC	; *26*	(CC->4C)
0286           DB      $01
0287           DB      $46
0288           DB      $CB	; *27*	(CB->4B)
0289           DB      $0C
028A           DB      $91
028B           DB      $C8	; *28*	(C8->48)
028C           DB      $B6
028D           DB      $FD
028E           DB      $E1
028F           DB      $9B
0290           DB      $7E
0291           DB      $85
0292           DB      $FD
0293           DB      $FF
0294           DB      $61
0295           DB      $79
0296           DB      $2D
0297           DB      $0A
0298           DB      $24
0299           DB      $C9	; *29*	(C9->49)
029A           DB      $6A
029B           DB      $FC
029C           DB      $57
029D           DB      $EC
029E           DB      $F5
029F           DB      $FB
02A0           DB      $08
02A1           DB      $56
02A2           DB      $AB
02A3           DB      $02
02A4           DB      $CC
02A5           DB      $CB	; *30*	(CB->4B)
02A6           DB      $BF
02A7           DB      $04
02A8           DB      $ED
02A9           DB      $CA	; *31*	(CA->4A)
02AA           DB      $E1
02AB           DB      $BF
02AC           DB      $DD
02AD           DB      $03
02AE           DB      $D1
02AF           DB      $CB	; *32*	(CB->4B)
02B0           DB      $95
02B1           DB      $29
02B2           DB      $01
02B3           DB      $E6
02B4           DB      $C8
02B5           DB      $0D
02B6           DB      $C3
02B7           DB      $C8	; *33*	(C8->48)
02B8           DB      $CD
02B9           DB      $62
02BA           DB      $F3
02BB           DB      $5A
02BC           DB      $E3
02BD           DB      $FF
02BE           DB      $A1
02BF           DB      $40
02C0           DB      $1E
02C1           DB      $4A
02C2           DB      $02
02C3           DB      $59
02C4           DB      $0D
02C5           DB      $8F
02C6           DB      $CA	; *34*	(CA->4A)
02C7           DB      $FC
02C8           DB      $02
02C9           DB      $97
02CA           DB      $9B
02CB           DB      $08
02CC           DB      $02
02CD           DB      $09
02CE           DB      $F5
02CF           DB      $09
02D0           DB      $2A
02D1           DB      $62
02D2           DB      $BB
02D3           DB      $01
02D4           DB      $E6
02D5           DB      $C8
02D6           DB      $04
02D7           DB      $F0
02D8           DB      $CA	; *35*	(CA->4A)
02D9           DB      $F8
02DA           DB      $DD
02DB           DB      $A8
02DC           DB      $02
02DD           DB      $C3
02DE           DB      $C9	; *36*	(C9->49)
02DF           DB      $7F
02E0           DB      $14
02E1           DB      $94
02E2           DB      $C8	; *37*	(C8->48) !!
02E3           DB      $02
02E4           DB      $5C
02E5           DB      $FB
02E6           DB      $A0
02E7           DB      $FF
02E8           DB      $22
02E9           DB      $02
02EA           DB      $52
02EB           DB      $A9
02EC           DB      $02
02ED           DB      $19
02EE           DB      $09
02EF           DB      $4D
02F0           DB      $A7
02F1           DB      $09
02F2           DB      $ED
02F3           DB      $AA
02F4           DB      $02
02F5           DB      $5C
02F6           DB      $0C
02F7           DB      $43
02F8           DB      $C8	; *38*	(C8->48)
02F9           DB      $B5
02FA           DB      $EA
02FB           DB      $3F
02FC           DB      $E3
02FD           DB      $BA
02FE           DB      $40
02FF           DB      $C2
0300           DB      $FF
0301           DB      $FF
0302           DB      $11
0303           DB      $FF
0304           DB      $07
0305           DB      $43
0306           DB      $C9	; *39*	(C9->49)
0307           DB      $E4
0308           DB      $9A
0309           DB      $84
030A           DB      $AA
030B           DB      $7F
030C           DB      $02
030D           DB      $07
030E           DB      $ED
030F           DB      $C9	; *40*	(C9->49)
0310           DB      $FA
0311           DB      $7E
0312           DB      $BF
0313           DB      $FF
0314           DB      $FF
0315           DB      $45
0316           DB      $17
0317           DB      $26
0318           DB      $C8	; *41*	(C8->48) !!
0319           DB      $D4
031A           DB      $98
031B           DB      $02
031C           DB      $1C
031D           DB      $02
031E           DB      $DC
031F           DB      $02
0320           DB      $1C
0321           DB      $02
0322           DB      $52
0323           DB      $FD
0324           DB      $20
0325           DB      $FD
0326           DB      $8C
0327           DB      $02
0328           DB      $1C
0329           DB      $DF
032A           DB      $02
032B           DB      $1C
032C           DB      $06
032D           DB      $ED
032E           DB      $11
032F           DB      $2A
0330           DB      $28
0331           DB      $C8	; *42*	(C8->48) !!
0332           DB      $6A
0333           DB      $02
0334           DB      $1C
0335           DB      $02
0336           DB      $3C
0337           DB      $9F
0338           DB      $02
0339           DB      $1C
033A           DB      $02
033B           DB      $3C
033C           DB      $05
033D           DB      $99
033E           DB      $02
033F           DB      $1C
0340           DB      $02
0341           DB      $3C
0342           DB      $05
0343           DB      $0A
0344           DB      $8E
0345           DB      $02
0346           DB      $1C
0347           DB      $02
0348           DB      $42
0349           DB      $B9
034A           DB      $02
034B           DB      $1C
034C           DB      $9F
034D           DB      $02
034E           DB      $3C
034F           DB      $02
0350           DB      $1C
0351           DB      $9F
0352           DB      $02
0353           DB      $3C
0354           DB      $02
0355           DB      $1C
0356           DB      $9F
0357           DB      $02
0358           DB      $3C
0359           DB      $02
035A           DB      $1C
035B           DB      $01
035C           DB      $E6
035D           DB      $C8
035E           DB      $17
035F           DB      $8D
0360           DB      $C8	; *43*	(C8->48) !!
0361           DB      $26
0362           DB      $02
0363           DB      $31
0364           DB      $03
0365           DB      $38
0366           DB      $66
0367           DB      $6D
0368           DB      $91
0369           DB      $6D
036A           DB      $2D
036B           DB      $63
036C           DB      $06
036D           DB      $02
036E           DB      $63
036F           DB      $D1
0370           DB      $06
0371           DB      $F8
0372           DB      $FF
0373           DB      $9F
0374           DB      $46
0375           DB      $02
0376           DB      $15
0377           DB      $06
0378           DB      $25
0379           DB      $C8	; *44*	(C8->48)
037A           DB      $BE
037B           DB      $43
037C           DB      $FF
037D           DB      $FB
037E           DB      $C0
037F           DB      $08
0380           DB      $E9
0381           DB      $C9	; *45*	(C9->49)
0382           DB      $3C
0383           DB      $02
0384           DB      $3D
0385           DB      $E1
0386           DB      $DD
0387           DB      $9D
0388           DB      $83
0389           DB      $29
038A           DB      $E6
038B           DB      $C8	; *46*	(C8->48) !!
038C           DB      $01
038D           DB      $5F
038E           DB      $9D
038F           DB      $01
0390           DB      $07
0391           DB      $37
0392           DB      $1F
0393           DB      $9D
0394           DB      $01
0395           DB      $1D
0396           DB      $01
0397           DB      $1D
0398           DB      $01
0399           DB      $1F
039A           DB      $9E
039B           DB      $01
039C           DB      $1C
039D           DB      $01
039E           DB      $1C
039F           DB      $01
03A0           DB      $9D
03A1           DB      $01
03A2           DB      $5D
03A3           DB      $01
03A4           DB      $20
03A5           DB      $7C
03A6           DB      $01
03A7           DB      $3E
03A8           DB      $01
03A9           DB      $1C
03AA           DB      $01
03AB           DB      $20
03AC           DB      $27
03AD           DB      $54
03AE           DB      $01
03AF           DB      $5D
03B0           DB      $01
03B1           DB      $20
03B2           DB      $7C
03B3           DB      $01
03B4           DB      $01
03B5           DB      $45
03B6           DB      $C8	; *47*	(C8->48)
03B7           DB      $C3
03B8           DB      $01
03B9           DB      $87
03BA           DB      $C8	; *48*	(C8->48)
03BB           DB      $03
03BC           DB      $01
03BD           DB      $87
03BE           DB      $C9	; *49*	(C9->49)
03BF           DB      $01
03C0           DB      $01
03C1           DB      $68
03C2           DB      $CE	; *50*	(CE->4E)
03C3           DB      $E0
03C4           DB      $01
03C5           DB      $67
03C6           DB      $CF	; *51*	(CF->4F)
03C7           DB      $07
03C8           DB      $0A
03C9           DB      $03
03CA           DB      $D9	; *52*	(D9->59)	BLUE CROWN
03CB           DB      $01
03CC           DB      $02
03CD           DB      $27
03CE           DB      $D9	; *53*	(D9->59)	YELLOW EYE
03CF           DB      $35
03D0           DB      $01
03D1           DB      $47
03D2           DB      $D9	; *54*	(D9->59)	RED MOUTH
03D3           DB      $15
03D4           DB      $04
03D5           DB      $48
03D6           DB      $D9	; *55*	(D9->59)	RED TONGUE
03D7           DB      $02
03D8           DB      $01
03D9           DB      $8B
03DA           DB      $D9	; *56*	(D9->59)
03DB           DB      $03
03DC           DB      $01
03DD           DB      $AB
03DE           DB      $D9	; *57*	(D9->59)
03DF           DB      $03
03E0           DB      $07
03E1           DB      $0E
03E2           DB      $15
03E3           DB      $1C
03E4           DB      $23
03E5           DB      $2A
03E6           DB      $31
03E7           DB      $38	; ################ END OF GRAPHIC BLOCK ################

03E8           LD      A,$FE	; SUBROUTINE USED BY THE TAPE LOADING ROUTINE
03EA           LD      DE,$2000
03ED           INC     D
03EE           EX      AF,AF'
03EF           DEC     D
03F0           LD      A,$4F
03F2           OUT     ($FE),A
03F4           IN      A,($FE)
03F6           RRA
03F7           AND     $20
03F9           OR      $02
03FB           LD      C,A
03FC           CP      A
03FD           RET     NZ

03FE           CALL    $0479	;								---@@@(11)0400:04->14
0401           JR      NC,$03FD
0403           LD      HL,$0415
0406           DJNZ    $0406
0408           DEC     HL
0409           LD      A,H
040A           OR      L
040B           JR      NZ,$0406
040D           CALL    $0475	;								---@@@(12)040F:04->14
0410           JR      NC,$03FD
0412           LD      B,$9C
0414           CALL    $0475	;								---@@@(13)0416:04->14
0417           JR      NC,$03FD
0419           LD      A,$C6
041B           CP      B
041C           JR      NC,$03FE
041E           INC     H
041F           JR      NZ,$0412
0421           LD      B,$C9
0423           CALL    $0479	;								---@@@(14)0425:04->14
0426           JR      NC,$03FD
0428           LD      A,B
0429           CP      $D4
042B           JR      NC,$0421
042D           CALL    $0479	;								---@@@(15)042F:04->14
0430           RET     NC

0431           LD      A,C
0432           XOR     $03
0434           LD      C,A
0435           LD      H,$00
0437           LD      B,$B0
0439           JR      $045A
043B           EX      AF,AF'
043C           JR      NZ,$0445
043E           JR      NC,$044F
0440           LD      (IX+$00),L
0443           JR      $0454
0445           RL      C
0447           XOR     L
0448           RET     NZ

0449           LD      A,C
044A           RRA
044B           LD      C,A
044C           INC     DE
044D           JR      $0456
044F           LD      A,(IX+$00)
0452           XOR     L
0453           RET     NZ

0454           INC     IX
0456           DEC     DE
0457           EX      AF,AF'
0458           LD      B,$B2
045A           LD      L,$01
045C           CALL    $0475	;								---@@@(16)045E:04->14
045F           RET     NC

0460           LD      A,$CB
0462           CP      B
0463           RL      L
0465           LD      B,$B0
0467           JP      NC,$045C	;								---@@@(17)0469:04->14
046A           LD      A,H
046B           XOR     L
046C           LD      H,A
046D           LD      A,D
046E           OR      E
046F           JR      NZ,$043B
0471           LD      A,H
0472           CP      $01
0474           RET		; END SUBROUTINE USED BY TAPE LOADING ROUTINE

0475           CALL    $0479	; SUBROUTINE USED BY THE ABOVE					---@@@(18)0477:04->14
0478           RET     NC

0479           LD      A,$16
047B           DEC     A
047C           JR      NZ,$047B
047E           AND     A
047F           INC     B
0480           RET     Z

0481           LD      A,$7F
0483           IN      A,($FE)
0485           RRA
0486           RET     NC

0487           XOR     C
0488           AND     $20
048A           JR      Z,$047F
048C           LD      A,C
048D           CPL
048E           LD      C,A
048F           AND     $07
0491           OR      $48
0493           OUT     ($FE),A
0495           SCF
0496           RET		; END SUBROUTINE USED BY THE ABOVE

0497           LD      A,$01	; ############## START CHECKSUM ROUTINE ################
0499           OUT     ($FE),A	; set "O6" to 0, CPU access to DRAM#1 instead of VRAM
049B           LD      HL,$04AF	; address of code block below					---@@@(19)049D:04->14
049E           LD      DE,$E000	; beginning of upper half of DRAM#1 (6000 in BASIC config)
04A1           LD      BC,$0017
04A4           LDIR		; copy code block to beginning of upper half of DRAM#1
04A6           LD      A,$41
04A8           OUT     ($FE),A	; set "O6" to 1, CPU access to VRAM instead of DRAM#1
04AA           LD      HL,$6000
04AD           JR      $04C9
				; ######## code block ########
				; this block is copied to E000h, and after loading OPUS (BASIC clears the memory)
				; will be available at 6000h. If then run (using the command
				; "E 6000" in monitor mode) it will save the OPUS code in two 8KB blocks.
04AF           LD      IX,$0000
04B3           PUSH    IX	; 0000 is the return addr after calling this routine (reset OPUS)
04B5           CALL    $600D	; this calls the entry point below
04B8           LD      IX,$2000
04BC           LD      DE,$2000	; entry point (6000 in BASIC/OPUS config)
04BF           LD      A,$FE
04C1           SCF
04C2           CALL    $04C2	; start of SAVE routine in BASIC (also exactly THIS address !!)
04C5           RET		; ######## end code block #########

04C6           LD      HL,$0000
04C9           PUSH    HL
04CA           LD      B,$08	; loop counter
04CC           LD      HL,$4000
04CF           LD      IY,$07F0	; start of BASIC LOAD code and also BASIC checksum data		---@@@(20)04D2:07->17
04D3           LD      IX,$DA8C	; addr of color attr for color pattern under logo (within video mem)
04D7           SET     7,(IX+$00) ; set BLINK attribute for first cell of color pattern <--- <--|
04DB           PUSH    BC	;								|
04DC           LD      DE,$0800	;								|
04DF           EXX		;								|
04E0           LD      HL,$0000	;								|
04E3           EXX		;								|
04E4           LD      A,(HL)	; <--- <--- <--- <--- <--- <--- | read from (4000)		|
04E5           EXX		;				|				|
04E6           LD      B,$08	; loop counter			|				|
04E8           LD      C,A	;				|				|
04E9           RLC     C	; CY = bit 7<--- <--- <---|	|				|
04EB           SBC     A,A	; A=00-CY		  |	|				|
04EC           LD      E,A	;			  |	|				|
04ED           LD      A,L	; (loop starts w HL=0000) |	|				|
04EE           AND     $40	;			  |	|				|
04F0           SUB     $01	;			  |	|				|
04F2           SBC     A,A	;			  |	|				|
04F3           XOR     E	;			  |	|				|
04F4           LD      E,A	;			  |	|				|
04F5           LD      A,H	;			  |	|				|
04F6           AND     $01	;			  |	|				|
04F8           SUB     $01	;			  |	|				|
04FA           SBC     A,A	;			  |	|				|
04FB           XOR     E	;			  |	|				|
04FC           LD      E,A	;			  |	|				|
04FD           LD      A,H	;			  |	|				|
04FE           AND     $08	;			  |	|				|
0500           SUB     $01	;			  |	|				|
0502           SBC     A,A	;			  |	|				|
0503           XOR     E	;			  |	|				|
0504           LD      E,A	;			  |	|				|
0505           LD      A,H	;			  |	|				|
0506           AND     $80	;			  |	|				|
0508           SUB     $01	;			  |	|				|
050A           SBC     A,A	;			  |	|				|
050B           XOR     E	;			  |	|				|
050C           RLCA		;			  |	|				|
050D           RL      L	;			  |	|				|
050F           RL      H	;			  |	|				|
0511           DJNZ    $04E9	; ---> 8 loops -----> --->|	|				|
0513           EXX		;				|				|
0514           INC     HL	; increment mem pointer		|				|
0515           DEC     DE	; decrement loop counter	|				|
0516           LD      A,D	;\ test if			|				|
0517           OR      E	;/ DE=0000			|				|
0518           JR      NZ,$04E4	; ---> ---> 800h loops---> ---> |				|
051A           EXX	;									|
051B           LD      E,(IY+$00) ; stored checksum lower 8 bits				|
051E           LD      D,(IY+$01) ; stored checksum upper 8 bits				|
0521           INC     IY	; increment checksum pointer					|
0523           INC     IY	; increment checksum pointer					|
0525           XOR     A	; reset CY flag							|
0526           SBC     HL,DE	; compare computed checksum with stored checksum		|
0528           JR      NZ,$052E	; ---> ---> --->|						|
052A           RES     7,(IX+$00) ;		| if chksum ok, reset blinking on color pattern |
052E           INC     IX	; <--- <--- <---| point to next cell in color pattern		|
0530           EXX		;								|
0531           POP     BC	; B = loop counter						|
0532           DJNZ    $04D7	; ---> 8 loops -----> ---> ---> ---> ---> ---> ---> ---> ---> ->|
0534           POP     HL
0535           EXX
0536           RST     $38	; ################## END CHECKSUM ROUTINE ##########################	---@@@(21)0536:FF->C7 (RST 0)
				; ################## TAPE LOADING ROUTINE ##########################
0537           LD      IX,$8000	; loading address of first half of BASIC
053B           SCF
053C           CALL    $03E8	; tape loading								---@@@(22)053E:03->13
053F           JR      NC,$0549
0541           LD      IX,$A000
0545           SCF
0546           CALL    $03E8	; tape loading								---@@@(23)0548:03->13
0549           JP      NC,$0004	;									---@@@(24)054B:00->10
054C           XOR     A	; A = 00
054D           LD      H,A	;\load HL register
054E           LD      L,A	;/with 0000 value (start addr in upcoming BASIC config)
054F           JP      $0051	; ################## END TAPE LOADING ROUTINE ######################	---@@@(25)0551:00->10
;	;
;	;			  ################## START CP/M LOADING ROUTINE ####################
0552           IN      A,($FD)	; read 1 byte from 8272 Data Register, it should be 80 (result of the
				; invalid command sent to 8272 by the instruction at 002A).
0554           CP      $80	; This tests whether 8272 present and properly reset.
0556           JP      NZ,$0004	; if not 80, restart execution from the beginning of the BOOT EPROM	---@@@(26)0558:00->10
0559           LD      HL,$0561	; 0561 is the addr of the 3rd instruction after this one
055C           LD      A,$41	; "41" is to be written to 8255 Port C after next line is executed
055E           JP      $0051	; (see comments for code at 0051)					---@@@(27)0560:00->10
;				; after the jump, "41" is written to 8255 Port C which means:
				; signal "O6" set to 1, "O5" set to 0, border color set to blue;
				; then bit 7 of register R is reset to 0 by instruction "LD R,A"
				; and configuration is changed to CP/M ("O6"=1). In this new config
				; execution starts from address stored in register HL previously.
				; The entire BOOT EPROM code was previously copied to beginning of DRAM#0
				; (see comments at 001D) and DRAM#0 is located at 0000 in CP/M config
				; so HL points now to exactly the next instruction below.
0561           LD      A,$01
0563           OUT     ($FE),A	; write 01 to port C of 8255 which means:
;				; set border to blue, set signal "SO" to 0, "O5" to 0 (lower half
				; of VRAM displayed), "O6" to 0 (CPU access to DRAM#1 instead of VRAM)
0565           LD      HL,$0000	;\
0568           LD      DE,$F800	; | BOOT EPROM code is again relocated, this time
056B           LD      BC,$0800	; | to F800-FFFF (top of RAM, end of DRAM#3)
056E           LDIR		;/  from this point on, addresses listed on the left side are actually added to F800
0570           JP      $FD73	; this jump continues execution with exactly the next line (0573+F800=FD73)
0573           IM      2	; ******* NOTE: THIS IS THE STACK BASE SET AT THE BEGINNING OF THIS BOOT EPROM *********
0575           LD      HL,$FFE8	; CTC interrupt table start address
0578           LD      A,H	; upper half of CTC interrupt table start address (FF)...
0579           LD      I,A	; ...is stored in register I (see Z80 docs)
057B           LD      A,L	; lower half of CTC interrupt table start address (E8)...
057C           OUT     ($E3),A	; ... is sent to CTC channel 0 (Enable Interrupt, Counter Mode, Prescaler=256,
				; Falling Edge, Pulse Trigger, No Time Const., Continue, Vector)
				; MEANING: Interrupt Vector being used by all 4 channels!!
				; Interrupt Vector = 11101cc0 where cc is the CTC channel.
				; requesting the interrupt. So vector for CTC0 = E8, CTC1 = EA, CTC2 = EC, CTC3 = EE
				; The upper half of addr table pointer is FF which means 07 within this BOOT EPROM.
				; Thus the vector table is at 07E8 (byte read), 07EC (sector read) in this BOOT EPROM.
057E           LD      A,$FF	; data for CTC0 on next line: set CTC0 to counter mode and enable CTC0 interrupts
0580           OUT     ($E3),A	; write FF to CTC channel 0 (Enable Interrupt, Counter Mode, Prescaler=256,
				; Rising Edge, CLK/TRG Pulse Starts Timer, Time Const. Follows, Reset, Control).
				; MEANING: Reset, Enable Interrupts for Channel 0, a Time Constant follows.
0582           LD      A,$01	; time constant for CTC0 on next line: generate INT for each byte transferred from 8272 to 牌
0584           OUT     ($E3),A	; write 01 to CTC channel 0
				; MEANING: Time Constant byte (=01, for 1 byte read).
0586           LD      HL,$FFE4	; address of the 2 args (6F, 01) of 8272 Specify command (for DD) on next line
				; These args specify Head Load/Unload times, Step Rate and choose Non-DMA mode,
				; (SRT=10 ms, HUT=240 ms, HLT=0 ms, Non-DMA)
0589           CALL    $FF0B	; call CTC1+2_INIT (which also sends a Specify command)
058C           LD      B,$04	; B as counter, 4 = nr of times to repeat the cycle below, for 4 possible FDDs
058E           PUSH    BC	; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <----|
058F           LD      BC,$0204	; Code for Sense Drive Status cmd (04) with 1 arg (B=02)		|
0592           CALL    $FEBD	; call 8272_CMD	(run Sense Drive Status cmd to check if 8272 is ready)	|
0595           CALL    $FEF9	; call 8272_READ (read command result into (FFD5))			|
0598           POP     BC	;									|
0599           LD      A,($FFD5); actual addr 07D5 in this BOOT EPROM (Sense Dr Stat result)		|
059C           BIT     5,A	; test bit 5 of it (READY)						|
059E           JR      NZ,$05B6	; if bit 5 not zero (drive is READY), jump ahead to 05B6 ---> ---> ---> | ---> ->(FF95 has the nr.
05A0           LD      HL,$FF95	; address of a data byte actually located at 0795 in this BOOT EPROM	|	|of first drive
05A3           INC     (HL)	; increment data byte (arg for Sense Drive Stat, increment drive no#)	|	|found ready)
05A4           DJNZ    $058E	; ---> ---> ---> ---> repeat cycle 4 times for all 4 drives --> ---> --->	|
				; if no FDD responding properly, switch back to startup cfg			|
05A6           DI		; ################ CPM_TO_COBRA ##################				|
05A7           IM      0	;										|
05A9           XOR     A	;										|
05AA           LD      I,A	;										|
05AC           LD      HL,$0004	;										|	---@@@(28)05AE:00->10
05AF           LD      A,$C1	;										|
05B1           OUT     ($FE),A	; write C1 to port C of 8255 which means:					|
				; set "SO" to 1, "O6" to 1, "O5" to 0, border color to blue			|
05B3           LD      R,A	; set bit 7 of R to 1 ---> hardware config changes to startup config		|
05B5           JP      (HL)	; jump address in the new config (beginning of this BOOT EPROM)			|
	;													|
				; ############# begin actual CP/M loading <--- <--- <--- <--- <--- <--- <--- <--|
05B6           LD      BC,$0207	; 02 means 1 argument, 07 = opcode for 8272 Recalibrate command
05B9           CALL    $FEBD	; call 8272_CMD (send Recalibrate cmd to 8272 w.arg at FF95)
05BC           CALL    $FF40	; call 8272_SEEK_TEST (Sense Interrupt Status)
05BF           CALL    $FF31	; call 8272_COND_SEEK (Seek track #2 + Sense Interrupt Status)
05C2           LD      BC,$024A	; 02 means 1 argument, 4A = opcode for 8272 Read ID command (in Double Density)
05C5           CALL    $FEBD	; call 8272_CMD (send Read ID command in DD to 8272)
05C8           CALL    $FEF9	; call 8272_READ (read command result into (FFD5-FFDB))
05CB           LD      A,($FFD5); load first result byte of Read ID into register A
05CE           AND     $C0	; testing bits 6 and 7
05D0           JR      Z,$05E3	; if they are 0 (no errors in DD), jump 7 lines below ---> ---> ---> ---->
05D2           LD      HL,$FFAC	; > if errors reading DD, FDD must be SD, copy SD params block from 07AC |
05D5           LD      DE,$FF99	; > over cmd params block at 0799 within this BOOT EPROM code		 |
05D8           LD      BC,$000A	; > (to change future 8272 command params for Single Density).		 |
05DB           LDIR		; After this, (FF99)=02 means DD, 00 means SD (arg #5 of 8272 Read Data) |
05DD           LD      HL,$FFE6	; addr of the 2 args (BF, 17) of Specify command (for SD) on next line	 |
				; (SRT=5 ms, HUT=240 ms, HLT=22 ms, Non-DMA)				 |
05E0           CALL    $FF0B	; call CTC1+2_INIT (which also sends a Specify command)			 |
05E3           LD      A,($FF99); <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <-----|
05E6           OR      A	; test (FF99) if zero (initially 02, it is 02 if DD, 00 if SD)
05E7           LD      B,$04	; B used as counter** 		if DD (read 4 sectors = 4 x 512 = 2048 bytes)
05E9           LD      E,$01	; index to locate in memory the byte for sector number to use next
05EB           JR      NZ,$05EF	; if not SD  ---> --->|		B=04, C=(FFE7)=17 (the 2nd arg of Specify at 05E0)
05ED           LD      B,$10	; B used as counter** | 	if SD (read 16 sectors = 16 x 128 = 2048 bytes)
05EF           CALL    $FF54	; FDD_SECT_READ <-<---<  read 1 sector to mem starting at (FFD0-FFD1)=F400
05F2           INC     E	; next sector to try  | E=1...4 for DD, E=1...10h for SD
05F3           DJNZ    $05EF	; ---> ---> ---> ---->| (FFA3-FFA6) for DD, (FFB6-FFC6) for SD
05F5           LD      HL,$0000	;			(sectors 1,5,9,4 if DD, 01,07,0D,13,19,05,0B,11,17,03,09,0F,15,02,08,0E if SD)
05F8           LD      ($FFD0),HL ; (FFD0)&(FFD1) = 0000 = new start address for storage of data read from disk
05FB           LD      HL,$F400
05FE           PUSH    HL
05FF           POP     HL	; <--- jump here from 067D <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--<--|
0600           LD      B,$40	; 40h=64 directory entries to search (2048 bytes)					|
0602           LD      A,(HL)	; <--- <--- <--- <--- <--- <--- <--- <--| search max 64 (40h) times			|
0603           OR      A	;					| in steps of 32 (20h) bytes (=1 dir entry)	|
0604           JR      NZ,$061A	; ---> ---> ---> ------>  not 00 ?	| for a 00 byte (meaning USER 0) in data read	|
0606           PUSH    BC	; * 40xx		|		| from FDD. If no 00 byte found after 64 tries,	|
0607           PUSH    HL	; **F400+(20*count)	|		| reset BOOT EPROM				|
0608           LD      DE,$0009	;			|		| If 00 byte found, go 9 bytes after it and	|
060B           ADD     HL,DE	; HL=F409+(20*count)	|		| test to see if the 3 next bytes (filename	|
060C           EX      DE,HL	; HL=0009, DE=F409+...	|		| extension) contain "SYS" in their lower 7 bits|
060D           LD      HL,$FFDE	; HL=FFDE		|		| If they do, then continue executing code after|
0610           LD      B,$03	; 3 chars of a fname ext| to check	| this loop. If they are not, reset BOOT EPROM	|
0612           LD      A,(DE)	; A=(F409) <--- <--- <-	| <-----|	|						|
0613           AND     $7F	;			|	|	|						|
0615           CP      (HL)	; cmp sect w signature	| (SYS)	|	|						|
0616           JR      Z,$0622	; ---> ---> --->	|	|	|						|
0618           POP     HL	; **		|	|	|	|						|
0619           POP     BC	; *		|	|	|	|						|
061A           LD      DE,$0020	; <--- <--- <--	| <-----|	|	|						|
061D           ADD     HL,DE	; fwd 20 bytes	|		|	|						|
061E           DJNZ    $0602	; ---> ---> --->|---> ---> ---> ---> --->						|
0620           JR      $05A6	; CPM_TO_COBRA  |		|							|
0622           INC     DE	; <--- <--- <---|		|							|
0623           INC     HL	;				|							|
0624           DJNZ    $0612	; ---> ---> ---> ---> ---> ---->|							|
0626           POP     DE	; **DE=F400										|
0627           LD      HL,$0010	;					If "S", "Y", "S" or D3, D9, D3 found, go 16	|
062A           ADD     HL,DE	; HL=F410				(10h) bytes after the 00 previously found	|
062B           LD      DE,$FC00	; DE=FC00				before "SYS" and copy 16 (10h) bytes to FC00	|
062E           PUSH    DE	; (SP)=FC00				These bytes are the allocation table for the	|
062F           LD      BC,$0010	;					current directory entry				|
0632           LDIR		; 16 bytes from F410 to FC00. After this, HL=F420, DE=FC10				|
0634           EX      (SP),HL	; (SP)=F420=addr of next entry, HL=FC00=addr of allocation table			|
0635           LD      A,(HL)	; low byte of block address (07) for CHRIS.SYS or Kryss.SYS				|
0636           PUSH    HL	; (SP)=FC00 <--- <--- <--- <--- <--- <--- <--- <--- <--- <---- <--- <--- <------|	|
0637           LD      H,$00	;										|	|
0639           LD      L,A	; low byte of block address (07) for CHRIS.SYS or Kryss.SYS			|	|
063A           LD      BC,$03FF	; repeat next loop 3 times, C=FF						|	|
063D           SLA     L	; <--- <---| assume SD (8 sectors/block) and compute absolute sector addr	|	| <-- Block size is assumed to be 1K but for DD it is actually 2K.
063F           RL      H	; HL=HL*2  | as (block_addr*8) and adjust later (/4) if DD (2 sectors/block)	|	|     The trick is that the block number used is mangled to give
0641           DJNZ    $063D	; ---> --->|	(00111000=38h)							|	|     the correct target sector on current DD disks
0643           INC     HL	; HL=block addr*8+1=sect_addr_SD (sector numbers start at 1) (00111001=39h)	|	|
0644           LD      DE,($FF9F) ; 256B Sectors/cyl=36 (24h) if DD, 128B Sectors/cyl=26 (1Ah) if SD		|	| <-- DD sector size used here
0648           INC     C	; C = 00 for start <--- <--- <--- <--- <--					|	|     is different than real size (512B)
0649           SBC     HL,DE	; (sect_addr_SD) minus (sectors/cyl)	 |					|	|     used on today's CoBra disks
064B           JR      NC,$0648	; ---> ---> ---> ---> ---> ---> ---> --->|					|	|     (this code is old & translation
064D           ADD     HL,DE	; >> HL=(sect_addr_SD) mod (sect/cyl)=sect#_on_cyl_SD (0015 if DD, 0005 if SD)	|	|      algorithm was not updated, instead
;				; and C=(sect_addr_SD)/(sect/cyl)=cyl#		(01 if DD or 02 if SD)		|	|      the computing of data location was
064E           LD      A,($FF99); arg #4 of 8272 command (N=log2(bytes/sector)-log2(128))			|	|      just mangled to give correct result)
0651           OR      A	; test if 00 (Single Density)							|	|
0652           LD      B,$08	; 8 loops if SD									|	|
0654           JR      Z,$065E	; if Single Density (L=05) ---->|						|	|
0656           LD      B,$02	; 2 loops if DD			| adjust sect#_on_cyl for Double Density	|	|
0658           DEC     L	; ] L=L-1			| x MOD y = x - y * int(x/y) = expr		|	|
0659           SRL     L	; ] L=L/2			| then expr/4 = x/4 - y/4 * int(x/y) so here	|	|
065B           SRL     L	; ] L=L/2			| (adr*8) mod 36=adr*8-36*[(adr*8)/36]=expr	|	|
065D           INC     L	; ] L=(sect#_on_cyl-1)/4+1=06	| and expr/4=adr*2-9*[(adr*2)/9]=(adr*2) mod 9	|	|
065E           LD      A,$02	; <--- <--- <--- <--- <--- <----| so dividing by 4 gives the correct adjustment	|	|
0660           ADD     A,C	; cyl# + 2 because block numbers start on cyl #2 (03 if DD or 04 if SD)		|	|
0661           LD      D,A	; track# = 03 or 04 (DD or SD)							|	|
0662           LD      E,L	; sect# = 06 or 05 (DD or SD)							|	|
0663           LD      A,D	; <--- <--- 2 loops if DD, 8 loops if SD  <--- <--- <--- <---|			|	| read from disk to mem starting at 0000
0664           LD      ($FFD4),A; (FFD4)=track number in 8272_COND_SEEK			     | 03...04 (if DD)	|	| if DD read trk#3 sect#3 and trk#4 sect#7
0667           CALL    $FF54	; call FDD_SECT_READ	E=06,07	-->sect	3,7		     |			|	|
066A           LD      HL,($FF9A) ; L=final sector nr on a track (EOT), arg #6 of 8272 cmd   |			|	|
066D           INC     HL	; L=0A or 1B						     |			|	|
066E           INC     E	; used as index to determine sector no.			     | 06...07		|	|
066F           LD      A,E	;							     |			|	|
0670           CP      L	; comp index w max. sector no				     |			|	|
0671           JR      C,$0676	;				--> --->|		     |			|	|
0673           INC     D	;					|		     | 04...0B (if DD)	|	|
0674           LD      E,$01	;					|		     |			|	|
0676           DJNZ    $0663	; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->|			|	|
0678           POP     HL	; FC00										|	|
0679           INC     HL	; FC01										|	|
067A           LD      A,$0F	;										|	|
067C           AND     L	; 01										|	|
067D           JR      Z,$05FF	; no jump most likely	 --> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->|
067F           LD      A,(HL)	; (FC01)=00 most likely								|
0680           OR      A	;										|
0681           JR      NZ,$0636	; no jump most likely	 ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---->| 
0683           DI
0684           LD      HL,$0000
0687           LD      A,(HL)
0688           CP      $F3	; test if first byte of presumed CP/M loader code is F3 (should be 00)
068A           EXX
068B           LD      HL,$0043
068E           JP      Z,$FDAF	; if it is, go to CPM_TO_COBRA
0691           EXX
0692           JP      (HL)	; ########## End of actual CP/M loading ###########

0693           EX      AF,AF'	; ############## CTC0 (Byte Read) Interrupt Service Routine ####################
0694           LD      A,$7F	; control word for CTC channel 1 (in next instruction)
0696           OUT     ($EB),A	; write 7F to CTC channel 1 (Disable Interrupt, Counter Mode, Prescaler=256,
				; Rising Edge, Pulse Trigger, Time Const. Follows, Reset, Control)
				; MEANING: Reset Channel 1, resume operation after loading a time constant.
0698           LD      A,($FF9E); load A with data byte from address 079E (00)
069B           OUT     ($EB),A	; write time constant byte (00) to CTC channel 1
069D           EX      AF,AF'
069E           EI		; --------- CTC Channel 1 & 3 Interrupt service routine (does nothing) ---------
069F           RETI		; ##############################################################################

06A1           INI		; ############## Alternate CTC0 (Byte Read) Interrupt Service Routine ##########
06A3           EI		;
06A4           RETI		;
				; ############## CTC2 (Sector Read) Interrupt Service Routine ##################
06A6           LD      ($FFD2),HL ; HL contains the addr of the last byte read from disk by 8272_CMD1 plus 1
06A9           LD      HL,$FE93	; FE93 is the initial CTC0 interrupt routine address stored at FFE8
06AC           LD      ($FFE8),HL ; restore initial CTC0 interrupt routine address stored at FFE8
06AF           LD      C,$00	; C was used to store the port address for 8272 Data Register (FD)
06B1           EI		;
06B2           RETI		;
;				  ##################### 8272_POLL ##############################
06B4           IN      A,($F5)	; read 8272 Status Register			| this routine polls the 8272 Status Register
06B6           BIT     7,A	; test bit 7 (RQM)				| until 8272 is ready to send or receive
06B8           JR      Z,$06B4	; if bit 7 = 0 read 8272 Status Register again	| data to or from the CPU. When ready (RQM=1)
06BA           BIT     6,A	; test bit 6					| bit 6 is tested (DIO, 0=send/1=receive)
06BC           RET		;
;				  ##################### 8272_CMD ###############################
06BD           LD      HL,$FF95	; (command args addr=0795)
06C0           CALL    $FEB4	; call 8272_POLL ------ 8272_CMD_HL --------  <--- <--- <--- <---|
06C3           JP      NZ,$FDA6	; jump to CPM_TO_COBRA, if data out of 8272			 |
06C6           LD      A,C	; (C = opcode for 8272 command)					 |
06C7           OUT     ($FD),A	; send opcode to 8272 Data Register				 |
06C9           LD      C,(HL)	; load C with command arg from address (HL)			 |
06CA           INC     HL	; increment pointer to command args				 |
06CB           DJNZ    $06C0	; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->
06CD           RET
;				  ##################### 8272_CMD1 ##############################
06CE           LD      DE,$FF95	; start address for 8272 command arguments
06D1           LD      HL,$FEA1	; address of another interrupt routine (06A1 in the BOOT EPROM)
06D4           LD      ($FFE8),HL ; replace the CTC0 interrupt routine address in address table
06D7           LD      HL,($FFD0) ; initially (FFD0)=00, (FFD1)=F4, so HL=F400
06DA           JR      $06DF	; ---> --->|
06DC           LD      A,(DE)	; <--- <-- | <--- <--- <--- <--- <--- <--- <----|
06DD           INC     DE	;	   V					|
06DE           LD      C,A	;	   |save A in C bcoz A used by 8272_POLL|
06DF           CALL    $FEB4	; <--- <---| 8272_POLL				|
06E2           JP      NZ,$FDA6	; if not ready for new command, CPM_TO_COBRA	|
06E5           LD      A,C	;						|
06E6           LD      C,$FD	;						|
06E8           OUT     (C),A	; send contents of A to 8272 Data Register	|
06EA           DJNZ    $06DC	;  ---> ---> ---> ---> ---> ---> ---> ---> ---->|
;				; At this point, B=00, C=FD, HL=F400. The next instruction halts the CPU, waiting
				; for an interrupt from 8272 after each byte was read from disk.
				; The interrupt routine at FEA1 then writes the I/O bytes from (C=FD) to memory starting at (HL)
				; which is F400. HL is a memory pointer and B is a counter for this process (00-FF).
				; (B decremented & HL incremented by the INI instruction in the CTC0 alternate int. routine)
06EC           HALT		; wait for next interrupt <--- <--- <--- <---|
06ED           IN      A,($F5)	; read 8272 Status Register		     |
06EF           AND     $20	; test bit 5 (Non-DMA Execution Phase)	     |
06F1           JR      NZ,$06EC	; if "1" (Execution not finished) ---> ----->|
06F3           LD      HL,$FE93	; initial address of the CTC0 interrupt routine in the interrupt addr table
06F6           LD      ($FFE8),HL ; restore initial address of the CTC0 interrupt routine in the interrupt addr table

06F9           LD      HL,$FFD5	; ##################### 8272_READ ###############################
06FC           LD      B,$08	; ###     reads max 8 bytes from 8272 into memory at FFD5     ###
06FE           CALL    $FEB4	; 8272_POLL <---- <---- <---- <---- <---- <---- <---- <---- <---|
0701           RET     Z	; return if data to go from CPU into 8272 (normal return)	|
0702           IN      A,($FD)	; read from 8272 Data Register					|
0704           LD      (HL),A	; store data at address pointed to by HL			|
0705           INC     HL	; increment pointer						|
0706           DJNZ    $06FE	; if B not zero ---> ---> ---> ---> ---> ---> ---> ---> ---> --->
0708           JP      $FDA6	; ---> CPM_TO_COBRA

070B           DI		; ##################### CTC1+2_INIT ###########################
070C           LD      A,$7F	; control word for CTC channel 1 (in next instruction)
070E           OUT     ($EB),A	; write 7F to CTC channel 1 (Disable Interrupt, Counter Mode, Presc=256,
				; Rising Edge, Pulse Trigger, Time Const. Follows, Reset, Control)
				; MEANING: Reset Channel 1, resume operation after loading a time const.
0710           LD      A,($FF9E); load A with data byte from address 079E (00)
0713           OUT     ($EB),A	; write time constant byte (00) to CTC channel 1
0715           LD      A,$FF	; control word for CTC channel 2 (in next instruction)
0717           OUT     ($F3),A	; write FF to CTC channel 2 (Enable Interrupt, Counter Mode, Prescaler=256,
				; Rising Edge, Pulse Trigger, Time Const. Follows, Reset, Control)
				; MEANING: Reset Channel 2, resume operation after loading a time constant.
0719           LD      A,($FF9D); load A with data byte from address 079D (02)
071C           OUT     ($F3),A	; write time constant byte (02) to CTC channel 2
071E           EI		;
071F           LD      BC,$0303	; B=nr of args for 8272 command + 1, C=opcode for 8272 "Specify" command
0722           JR      $06C0	; ---> ---> jump to 8272_CMD_HL ---> --->

;				  ##################### 8272_CMD_SIS ##########################
0724           LD      BC,$0108	; 01 means no arguments (zero), 08 = opcode for 8272 Sense Interrupt Status
0727           CALL    $FEBD	; call 8272_CMD, send Sense Interrupt Status command to 8272
072A           CALL    $FEF9	; call 8272_READ, read command result (2 bytes) into memory at FFD5-FFD6
072D           LD      A,($FFD5); load command result byte 1 (ST0) into register A
0730           RET     
;				  ##################### 8272_COND_SEEK ########################
0731           LD      A,($FFD4); \  Compare (FFD4) (initially 02) - (FFD4)=track to seek
0734           LD      HL,$FF96	;  \ with (FF96) (initially 00)    - (FF96)=current track
0737           CP      (HL)	;  / and
0738           RET     Z	; /  return if equal
0739           LD      (HL),A	; replace (FF96) with (FFD4)
073A           LD      BC,$030F	; Seek command for 8272, with 2 arguments (drive, cyl=2), to be sent in next instruction
073D           CALL    $FEBD	; call 8272_CMD
				; --------------------- 8272_SEEK_TEST ------------------------
0740           CALL    $FF24	; call 8272_CMD_SIS and get result in A
				; (*** Sense Interrupt Status is mandatory after Seek or Recalibrate ***)
0743           BIT     5,A	; test bit 5 (Seek End)
0745           JR      Z,$0740	; if Seek not finished, go back 2 lines above (??? should it be 4 lines ???)
0747           AND     $D8	; check if errors or drive not ready
0749           JP      NZ,$FDA6	; ---> if so, jump to CPM_TO_COBRA
074C           CALL    $FF24	; 8272_CMD_SIS - send Sense Interrupt Status command to 8272 and get result in A <--
074F           CP      $80	; check if Invalid Command Issue						   |
0751           RET     Z	; return if so									   |
0752           JR      $074C	; go back 3 lines above ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->|

				; ##################### FDD_SECT_READ ###############################
0754           PUSH    BC	; 0417 > BC and DE are saved on stack so their contents
0755           PUSH    DE	; 0001 > can be restored at the end of this routine
0756           CALL    $FF31	; call 8272_COND_SEEK
0759           LD      D,$00	;
075B           LD      HL,($FFA1) ; (FFA1)=A2, (FFA2)=FF for DD    or  (FFA1)=B5, (FFA2)=FF for SD
075E           ADD     HL,DE	; result HL=FFA2+0001=FFA3 for DD or  HL=FFB5+0001=FFB6 for SD
075F           LD      A,(HL)	; (FFA3)=01 (for DD) or (FFB5)=01 (for SD)
0760           LD      ($FF98),A; (0798) is arg #4 of Read Data (Sector number)
0763           LD      B,$0A	; 10 loops to do next			;
0765           PUSH    BC	; BC=0A17 (B used as counter**)	 <--- <--- <--- <--- <--- <--- <--- <---|
0766           LD      A,($FF99); (FF99)=02 or 00							|
0769           OR      A	; (FF99) can be either 02 (initial val) or 00 if Read ID at 05C5 gave errors (see lines 05D2-05DB)
076A           LD      BC,$0906	; 06 = opcode for 8272 Read Data command with 8 args starting at FF95 (Single Density, MFM=0)
076D           JR      Z,$0771	; skip next line if A=00 (Read Data in Single Density)			|
076F           SET     6,C	; BC=0946 meaning 8272 Read Data command with 8 args starting at FF95	| bit 6 is MFM bit, MFM=1 means
;				; 46 = opcode for <Read Data - MT=0 (single side), MFM=1 (DD), no Skip> | Read Data in Double Density
				; **arguments:	- Side 0 drive found Ready				|
				; ---> @FF96 >>	- Cyl 00  (C=00)					|
				;		- Head 00 (H=00)					|
				; ---> @FF98 >>	- Sector Number 01 (R=01)				|
				; ---> @FF99 >>	- 512 bytes/sector (N=02) or 128 if N=00 (Singl Density)|
				;		- EOT=09 (End Of Track Sector Number)			| <-- 09 if DD, 1A if SD
				;		- GPL=2A (Gap 3 Length)					| <-- 2A if DD, 07 if SD
				;		- DTL=FF (Data Length, has no meaning for N != 00)	| <-- FF if DD, 80 if SD
0771           CALL    $FECE	; call 8272_CMD1, run Read Data command					| <-- data being read is saved at address stored in (FFD0-FFD1)
0774           XOR     A	; A=0	;								|
0775           OR      C	; C=00 after 8272_CMD1 (CTC2 interrupt sets C to 00)			|
0776           POP     BC	; BC=0A17 (B used as counter**)						|
0777           JR      NZ,$0787	; if C not zero, jump ---> ---> ---> -->|				|
0779           LD      HL,$FFD7	; (FFD7)=ST2 (result byte #3)		|				|
077C           LD      A,(HL)	;					|				|
077D           DEC     HL	; (FFD6)=ST1 (result byte #2)		|				|
077E           OR      (HL)	;					|				|
077F           JR      NZ,$0787	; if errors ST1 or ST0 != 00 ---> ----->|				|
0781           DEC     HL	; (FFD5)=ST0 (result byte #1)		|				|
0782           LD      A,(HL)	;					|				|
0783           AND     $D8	; check if err or drv not Ready 	|				|
0785           JR      Z,$078C	; if no error, jump ---> ---> --->|	|				|
0787           DJNZ    $0765	; ---> ---> ---> ---> ---> ---> ---> -->| -----> ---> ---> ---> ---> --->
0789           JP      $FDA6	; CPM_TO_COBRA			  |
;								  |
078C           LD      HL,($FFD2) ; <--- <--- <--- <--- <--- <----| CTC2 int. routine saved addr for next sector into (FFD2),(FFD3)
078F           LD      ($FFD0),HL ; update start mem address for next sector read from FDD
0792           POP     DE	; > restore BC and DE to the values they had
0793           POP     BC	; > before execution of this routine
0794           RET		; #################### END CP/M LOADING ROUTINE ####################

;				; ############## BEGIN OF DATA BLOCK ################
0795           DB      $00	;\  <<<--- arg #1 of max. 8 (Side and drive number)
0796           DB      $00	; | <<<--- arg #2 of 8272 Read Data (current track number)
0797           DB      $00	; | <<<--- arg #3 of 8272 Read Data (head selected)
0798           DB      $01	; | <<<--- arg #4 of 8272 Read Data (Sector number)
0799           DB      $02	;*| <<<--- arg #5 of 8272 Read Data (N=02, Double Density)		*
079A           DB      $09	; | <<<--- arg #6 of 8272 Read Data (EOT, final sector nr on track)	|
079B           DB      $2A	; | <<<--- arg #7							| Double Density
079C           DB      $FF	;/  <<<--- arg #8							|
079D           DB      $02	; CTC Channel 2 Time Constant - for Double Density \  2 x 256 = 512	| parameters
079E           DB      $00	; CTC Channel 1 Time Constant - for Double Density / (DD sector size)	|
079F           DB      $24	;   <<<--- No of sectors per cylinder in Double Density			| block
07A0           DB      $00	;									|
07A1           DB      $A2	;   <<<---| base pointer to beginning of translation table		|
07A2           DB      $FF	;*  <<<---| with DD sector numbers (next 9 bytes)			*
07A3           DB      $01	; N
07A4           DB      $05	; N
07A5           DB      $09	; N  9 sector numbers (01...09)
07A6           DB      $04	; N  to try with
07A7           DB      $08	; N  the Read Data
07A8           DB      $03	; N  command if
07A9           DB      $07	; N  Double Density
07AA           DB      $02	; N
07AB           DB      $06	; N
07AC           DB      $00	;*| <<<--- arg #5 of 8272 Read Data (N=00, Single Density)		*
07AD           DB      $1A	; | <<<--- arg #6 of 8272 Read Data (EOT, final sector nr on track)	|
07AE           DB      $07	; | <<<--- arg #7							| Single Density
07AF           DB      $80	;/  <<<--- arg #8							|
07B0           DB      $01	; CTC Channel 2 Time Constant - for Single Density \  1 x 128 = 128	| parameters
07B1           DB      $80	; CTC Channel 1 Time Constant - for Single Density / (SD sector size)	|
07B2           DB      $1A	;   <<<--- No of sectors per cylinder in Single Density			| block
07B3           DB      $00	;									|
07B4           DB      $B5	;   <<<---| base pointer to beginning of translation table		|
07B5           DB      $FF	;*  <<<---| with SD sector numbers (next 26 bytes)			*
07B6           DB      $01	; N
07B7           DB      $07	; N
07B8           DB      $0D	; N
07B9           DB      $13	; N
07BA           DB      $19	; N
07BB           DB      $05	; N
07BC           DB      $0B	; N
07BD           DB      $11	; N
07BE           DB      $17	; N
07BF           DB      $03	; N
07C0           DB      $09	; N
07C1           DB      $0F	; N  26 sector numbers (01...1A)
07C2           DB      $15	; N  to try with
07C3           DB      $02	; N  the Read Data
07C4           DB      $08	; N  command if
07C5           DB      $0E	; N  Single Density
07C6           DB      $14	; N
07C7           DB      $1A	; N
07C8           DB      $06	; N
07C9           DB      $0C	; N
07CA           DB      $12	; N
07CB           DB      $18	; N
07CC           DB      $04	; N
07CD           DB      $0A	; N
07CE           DB      $10	; N
07CF           DB      $16	; N
07D0           DB      $00	; \these 2 bytes contain the start address for last sector
07D1           DB      $F4	; /read from floppy disk (F400) used by 8272_CMD1
07D2           DB      $00	; \these 2 bytes contain the start address for next sector
07D3           DB      $F4	; /to be read from floppy disk (see CTC2 Int. Routine & end of FDD_SECT_READ)
07D4           DB      $02	; <<<--- track to seek in next command
07D5           DB      $41	; A	\  storage area
07D6           DB      $52	; R	 | for result data
07D7           DB      $4D	; M	 | from 8272_READ
07D8           DB      $41	; A	 | (7 bytes)
07D9           DB      $26	; &	 |
07DA           DB      $24	; $	 |
07DB           DB      $4F	; O	/
07DC           DB      $46	; F
07DD           DB      $54	; T
07DE           DB      $53	; S
07DF           DB      $59	; Y
07E0           DB      $53	; S
07E1           DB      $38	; 8
07E2           DB      $30	; 0
07E3           DB      $6B	; k
07E4           DB      $6F	; o \ arguments for a "Specify" command: Step Rate Time = B (5 ms),
07E5           DB      $01	;   / Head Unload Time = F (240 ms), Head Load Time = 0B (22 ms), Non-DMA
07E6           DB      $BF	;\ arguments for a "Specify" command: Step Rate Time = B (5 ms),
07E7           DB      $17	;/ Head Unload Time = F (240 ms), Head Load Time = 0B (22 ms), Non-DMA
07E8           DB      $93	;\ interrupt routine address = FE93 (0693 within this BOOT EPROM)
07E9           DB      $FE	;/ for CTC Channel 0 (Byte Read)
07EA           DB      $9E	;\ interrupt routine address = FE9E (069E within this BOOT EPROM)
07EB           DB      $FE	;/ for CTC Channel 1 (Not used)
07EC           DB      $A6	;\ interrupt routine address = FEA6 (06A6 within this BOOT EPROM)
07ED           DB      $FE	;/ for CTC Channel 2 (Sector Read)
07EE           DB      $9E	;\ interrupt routine address = FE9E (069E within this BOOT EPROM)
07EF           DB      $FE	;/ for CTC Channel 3 (Not used)
;				; ################ END OF DATA BLOCK ################
;
;				  ################ START OF BASIC LOADING ROUTINE #################
07F0           LD      A,$0F	; control word to be written to 8255 meaning "set bit 7 of Port C"
07F2           OUT     ($DF),A	; which is signal "SO" which drives pin A14 of BASIC EPROM (>= 32K)
;				  that means the BASIC EPROM must have BASIC code at 4000 (or C000)
;				  ################ START OF OPUS LOADING ROUTINE ##################
07F4           LD      HL,$0000	; jump address after hardware configuration change
07F7           EXX
07F8           RST     $38	; jump to the BASIC CONFIGURATION ROUTINE					---@@@(29)07F8:FF->C3
07F9           RST     38	;										---@@@(30)07F9:FF->38
07FA           RST     38	;										---@@@(31)07FA:FF->10
07FB           RST     38
07FC           RST     38
07FD           RST     38
07FE           RST     38
07FF           RST     38
